package models;
import java.util.*;

import javax.persistence.*;

import play.data.validation.*;
import play.db.jpa.*;
 
@Entity
public class Bateau extends Model 
{
	@Required
	@ManyToOne
	public Couleur couleur;
	
	@Required
	@MaxSize(50)
	public String nom;
	
	@Max(359)
	@Min(0)		
	public float orientation;
	
	@OneToMany(mappedBy="bateau", cascade=CascadeType.ALL)
	public List<Voile> voiles;
	
	@OneToMany(mappedBy="bateau", cascade=CascadeType.ALL)
	public List<Manoeuvre> manoeuvres;
	
	@OneToMany(mappedBy="bateau", cascade=CascadeType.ALL)
	public List<Participe> participes;
	
	@ManyToOne
	public Coordonnee coordonnee;
	
	@Required
	@ManyToOne
    public Modele_bateau modele;
	
	public Bateau(Couleur couleur, String nom, Utilisateur utilisateur, float orientation, Modele_bateau modele) 
	{
		this.participes = new ArrayList<Participe>();
		this.manoeuvres = new ArrayList<Manoeuvre>();
		this.voiles = new ArrayList<Voile>();
		this.voiles.add(new Spi(0, this));
		this.voiles.add(new Foc(0, this, 0));
		this.voiles.add(new GrandVoile(0, this, 0));
		this.couleur = couleur;
		this.nom = nom;
		this.orientation = orientation;
		this.coordonnee = null;
		this.modele = modele;
	}
	
	
	
	public Bateau(Couleur couleur, String nom, float orientation,
			Utilisateur utilisateur, List<Voile> voiles,
			List<Manoeuvre> manoeuvres, List<Participe> participes,
			Modele_bateau modele)
	{
		this.couleur = couleur;
		this.nom = nom;
		this.orientation = orientation;
		this.voiles = voiles;
		this.manoeuvres = manoeuvres;
		this.participes = participes;
		this.modele = modele;
		this.coordonnee = null;
	}
	
	public Bateau(Couleur couleur, Modele_bateau modele, String nom) 
	{
		this.participes = new ArrayList<Participe>();
		this.manoeuvres = new ArrayList<Manoeuvre>();
		this.voiles = new ArrayList<Voile>();
		this.voiles.add(new Spi(0, this));
		this.voiles.add(new Foc(0, this, 0));
		this.voiles.add(new GrandVoile(0, this, 0));
		this.couleur = couleur;
		this.nom = nom;
		this.orientation = 0;
		this.coordonnee = null;
		this.modele = modele;
	}	



	public String toString()
	{
		return "[" + this.id + "] " + this.nom;
	}


	// Fait bouger le bateau toutes les secondes
	public Coordonnee deplacer(long course_id) 
	{
		Course course = Course.findById(course_id);
		Coordonnee coord_meteo = Coordonnee.find("byCarte_id", course.modele.carte.id).first();
		Condition_meteo condition = coord_meteo.condition;
		
		int allure = 0; // 0 = face, 1 = arrière, 2 = coté
		int vitesse = 0;
		int surface_totale = (int) (this.voiles.get(0).surface + this.voiles.get(1).surface + this.voiles.get(2).surface);
		
		int deplacement_x = 0;
		int deplacement_y = 0;
		
		
		if((condition.direction_vent + this.orientation)%360 < 45 || (condition.direction_vent + this.orientation)%360 > 315)
			allure = 0;
		else if((condition.direction_vent + this.orientation)%360 > 150 && (condition.direction_vent + this.orientation)%360 < 250)
			allure = 2;
		else
			allure = 1;
		
		
		System.out.println("allure de " + this.nom + " : " + allure);
		
		// Vent de face
		if(allure == 0){
			// Le bateau n'avance pas.
		}
		
		// Vent arrière
		else if(allure == 1)
		{
			vitesse = (int) (1 * condition.force_vent * surface_totale)/1000;
			deplacement_x = 0;
			deplacement_y = (int) vitesse/2;
		}
			
		
		// Vent de coté
		else
		{
			vitesse = (int) (1.5 * condition.force_vent * surface_totale)/1000;
			if(this.orientation < 180)
				deplacement_x = (int) vitesse/2;
			
			else
				deplacement_x = -(int) vitesse/2;
			
			deplacement_y = (int) vitesse/2;			
		}
		
		try{
			Coordonnee nouvelle_pos = Coordonnee.find("byPosition_xAndPosition_y", this.coordonnee.position_x + deplacement_x, this.coordonnee.position_y + deplacement_y).first();
			if(nouvelle_pos.est_eau)
			{
				this.coordonnee = nouvelle_pos;
				this.save();					
			}
		}
		catch(Exception e){
			System.out.println("Erreur de coordonnees");
		}
		
		return this.coordonnee;
	}	
}
